"""
有道翻译反爬虫

核心参数逻辑：

t: md5(浏览器版本号：5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36)
r: 当前时间毫秒数字符串
i: r + 0-9随机一位数字字符串
sign: md5("fanyideskweb" + 翻译内容 + i + "Y2FYu%TNSbMCxc3t2u^XT")
r = {ts: r, bv: t, salt: i, sign: sign}

method: POST

参数示例：
i: 翻译内容
from: AUTO
to: AUTO
smartresult: dict
client: fanyideskweb
salt: r.salt
sign:  r.sign
lts: r.ts
bv: r.bv
doctype: json
version: 2.1
keyfrom: fanyi.web
action: FY_BY_REALTlME
"""
import time
import string
import random
from hashlib import md5
import requests


class YouDaoFanYi(object):
    """有道翻译反爬虫"""
    host = 'https://fanyi.youdao.com/'
    url = 'https://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule'
    AppVersion = '5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36'
    headers = {
        'Host': 'fanyi.youdao.com',
        'Origin': 'https://fanyi.youdao.com',
        'Referer': 'https://fanyi.youdao.com/',
        'sec-ch-ua': '"Chromium";v="92", " Not A;Brand";v="99", "Google Chrome";v="92"',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36',
        'X-Requested-With': 'XMLHttpRequest'
    }

    def __new__(cls, *args, **kwargs):
        if not hasattr(cls, '_instance'):
            cls._instance = super(YouDaoFanYi, cls).__new__(cls)
        return cls._instance

    def __init__(self):
        self.session = requests.session()
        self.session.get(self.host)     # todo 请求首页缓存首页cookie等信息

    def translate(self, text: str):
        """翻译"""
        if not text:
            return
        r = self.generate_encrypt_data(text)
        if not r:
            return
        data = {
            'i': text,
            'from': 'AUTO',
            'to': 'AUTO',
            'smartresult': 'dict',
            'client': 'fanyideskweb',
            'salt': r.get('salt'),
            'sign': r.get('sign'),
            'lts': r.get('ts'),
            'bv': r.get('bv'),
            'doctype': 'json',
            'version': 2.1,
            'keyfrom': 'fanyi.web',
            'action': 'FY_BY_REALTlME'
        }
        res = self.session.post(url=self.url, data=data, headers=self.headers)
        if res.status_code != 200:
            return
        json_result = res.json()
        errorCode = json_result.get('errorCode')
        if errorCode != 0:
            return
        translate_result = json_result.get('translateResult')[0][0]
        if not translate_result:
            return
        return f"text: {text}, 翻译结果为：{translate_result.get('tgt')}"

    def generate_encrypt_data(self, text: str):
        """
        生成加密参数
        t: md5(浏览器版本号：5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36)
        r: 当前时间毫秒数字符串
        i: r + 0-9随机一位数字字符串
        sign: md5("fanyideskweb" + 翻译内容 + i + "Y2FYu%TNSbMCxc3t2u^XT")
        r = {ts: r, bv: t, salt: i, sign: sign}
        """
        if not text:
            return
        t = self.generate_md5(self.AppVersion)
        r = str(int(time.time() * 1000))
        i = r + str(random.choice(string.digits))
        sign = self.generate_md5(f"fanyideskweb{text}{i}Y2FYu%TNSbMCxc3t2u^XT")
        return {'ts': r, 'bv': t, 'salt': i, 'sign': sign}

    @staticmethod
    def generate_md5(text: str):
        """生成md5签名"""
        if not text:
            return
        encrypt = md5()
        encrypt.update(text.encode('utf-8'))
        return encrypt.hexdigest()


if __name__ == '__main__':
    fan_yi = YouDaoFanYi()
    print(fan_yi.translate('编程'))
    print(fan_yi.translate('你好，世界'))
